#include "jsapi.h"
#include "js-engine.h"
#include "desktopClasses.h"
#include "mainview-parser.h"

static JSBool elements_new(JSContext *cx, JSObject *obj, uintN argc, jsval *args, jsval *rval);
static JSBool elements_GetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp);
static JSBool elements_item(JSContext *cx, JSObject *obj, uintN argc, jsval *args, jsval *rval);
struct JSFunctionSpec elements_methods[] = {
    {"item", elements_item, 1, 0, 0},
};

JSClass elementsClass = 
    { "elements", JSCLASS_HAS_PRIVATE,
      JS_PropertyStub, JS_PropertyStub, elements_GetProperty, JS_PropertyStub,
      JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub,
      JSCLASS_NO_OPTIONAL_MEMBERS
    };

struct property_parser elements_parser[] = {
    /* from basicElement */
    {"cursor", set_property_string_value},
    {"dropTarget", set_property_boolean_value},
    {"enabled", set_property_boolean_value},
    {"height", set_property_integer_value},
    {"hitTest", set_property_string_value},
    {"mask", set_property_string_value},
    {"name", set_property_string_value},
    {"offsetHeight", set_property_integer_value},
    {"offsetWidth", set_property_integer_value},
    {"offsetX", set_property_integer_value},
    {"offsetY", set_property_integer_value},
    {"opacity", set_property_integer_value},
    {"pinX", set_property_integer_value},
    {"pinY", set_property_integer_value},
    {"rotation", set_property_float_value},
    {"tagName", set_property_string_value},
    {"tooltip", set_property_string_value},
    {"width", set_property_integer_value},
    {"visible", set_property_boolean_value},
    {"x", set_property_integer_value},
    {"y", set_property_integer_value},
		
    {NULL, NULL},
};

static JSBool elements_GetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
{
    desktop_element *widget = JS_GetPrivate(cx, obj);
    gchar *key = JS_GetStringBytes(JSVAL_TO_STRING(id));
    if(g_strcasecmp(key, "count") == 0 && widget){
        int length = g_list_length(widget->children);
        *vp = INT_TO_JSVAL(length);
        return JS_TRUE;
    }
    return JS_TRUE;
}

JSBool elements_item(
		     JSContext *cx, JSObject *obj, uintN argc, jsval *args, jsval *rval) {
    desktop_element *widget = JS_GetPrivate(cx, obj);
    gchar *key = JS_GetStringBytes(JSVAL_TO_STRING(args[0]));

    if (widget) {
        int i;
        for (i = 0; i < g_list_length(widget->children); i++) {
            desktop_element *child = g_list_nth_data(widget->children, i);
            if (child->name && g_strcasecmp(key, child->name) == 0) {
                *rval = OBJECT_TO_JSVAL(child->jsobj);
                return JS_TRUE;
            }
        }
    } else {
        return JS_FALSE;
    }
    *rval = JSVAL_VOID;
    return JS_TRUE;
}

static JSBool elements_new(JSContext *cx, JSObject *obj, uintN argc, jsval *args, jsval *rval)
{
    g_return_val_if_fail(JS_DefineFunctions(cx, obj, elements_methods), FALSE);
    return JS_TRUE;
}

JSObject *elementsClass_init(js_engine *engine, JSObject *parent)
{
    JSObject *proto = NULL;
    proto = JS_InitClass(engine->cx, engine->glob, parent,
			 &elementsClass, elements_new,
			 0,NULL,NULL,NULL,NULL);
    g_return_val_if_fail(proto, FALSE);
    g_return_val_if_fail(JS_DefineFunctions(engine->cx, proto, elements_methods), FALSE);
    return proto;
}
